/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.compose.ui.tooling.preview

import kotlin.jvm.JvmDefaultWithCompatibility
import kotlin.reflect.KClass

/**
 * Interface to be implemented by any provider of values that you want to be injected as @[Preview]
 * parameters. This allows providing sample information for previews.
 */
@JvmDefaultWithCompatibility
interface PreviewParameterProvider<T> {
    /** [Sequence] of values of type [T] to be passed as @[Preview] parameter. */
    val values: Sequence<T>

    /** Returns the number of elements in the [values] [Sequence]. */
    val count
        get() = values.count()

    /**
     * Returns a descriptive display name for the value at a given [index] from the [values]
     * [Sequence].
     *
     * This name is used in the preview UI to help identify individual preview cases generated by
     * this provider. This allows for position-based naming schemes (e.g., "Step 1", "Step 2"). To
     * create a name based on the value's content, the value would need to be retrieved from the
     * [values] sequence within this method's implementation.
     *
     * For example, for a `PreviewParameterProvider` representing steps in a flow, you might return
     * `"Step ${index + 1}"`.
     *
     * If `null` or an empty string is returned, the preview UI will fall back to a default name
     * determined by Android Studio.
     *
     * @param index The position of the value in the [values] [Sequence].
     * @return A custom name for the preview for the value at the given [index], or `null` or an
     *   empty string to use the default.
     */
    fun getDisplayName(index: Int): String? = null
}

/**
 * [PreviewParameter] can be applied to any parameter of a @[Preview].
 *
 * @param provider A [PreviewParameterProvider] class to use to inject values to the annotated
 *   parameter.
 * @param limit Max number of values from [provider] to inject to this parameter.
 */
annotation class PreviewParameter(
    val provider: KClass<out PreviewParameterProvider<*>>,
    val limit: Int = Int.MAX_VALUE,
)
